<?php
/**
 * Created by PhpStorm.
 * User: ownfi
 * Date: 2017-04-09
 * Time: 11:20
 */

namespace App\Services\Impl;


use App\Common\Constant\Params;
use App\Models\Master;
use App\Models\MasterCash;
use App\Models\MasterFund;
use App\Models\MasterTradeLog;
use App\Models\MasterWallet;
use App\Models\Order;
use App\Services\IMasterLogService;
use App\Services\ISystemService;
use App\Services\IWalletService;
use DB;
use Log;

class MasterLogServiceImpl implements IMasterLogService
{
    private $systemService;

    /**
     * PayServiceImpl constructor.
     */
    public function __construct(ISystemService $systemService)
    {
        $this->systemService = $systemService;
    }

    public function PayAssureFundLog(MasterFund $fundOrder,$pay_method)
    {
        DB::beginTransaction();
        try{
            //生成交易流水号
            $trade_number = $this->systemService->genTradeNumber();

            $master = Master::find($fundOrder->master_id);
            $wallet = MasterWallet::where('master_id',$fundOrder->master_id)->lockForUpdate()->first();

            //是否是用余额支付的
            $pay_by_balance = $pay_method == Params::PAY_METHOD_BALANCE;
            //支付来源
            $source = [
                Params::PAY_METHOD_WEIXIN => Params::TRADE_SOURCE_WEIXIN ,
                Params::PAY_METHOD_ALIPAY => Params::TRADE_SOURCE_ALIPAY ,
                Params::PAY_METHOD_UNIONPAY => Params::TRADE_SOURCE_UNIONPAY ,
                Params::PAY_METHOD_BALANCE => Params::TRADE_SOURCE_BALANCE ,
            ][$pay_method];

            $ret = MasterTradeLog::create([
                'trade_number'=>$trade_number,
                'master_id'=>$fundOrder->master_id,
                'master_name'=>$master->real_name,
                'direction'=>Params::TRADE_DIRECTION_OUT,
                'amount'=>$fundOrder->amount,
                'type'=>Params::TRADE_TYPE_ASSURE,
                'source'=>$source,
                'balance'=>$pay_by_balance ? $wallet->balance - $fundOrder->amount : $wallet->balance,
                'assure_fund'=>$wallet->assure_fund + $fundOrder->amount,
                'order_number'=>$fundOrder->id,
                'order_serial_number'=>$fundOrder->order_number,
                'ip'=>getip(),
                'status'=>Params::TRADE_STATUS_WAITING,
            ]);

            if ($ret){
                DB::commit();
            }else{
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'PayAssureFundLog fail'));
                DB::rollBack();
            }

            return $ret;
        }catch (\Exception $e){
            DB::rollBack();
            throw $e;
        }
    }

    public function cashLog(MasterCash $cashOrder)
    {
        DB::beginTransaction();
        try{
            $wallet = MasterWallet::where('master_id',$cashOrder->master_id)->lockForUpdate()->first();
            $current_balance = $wallet->balance;
            $new_balance = $current_balance - $cashOrder->amount;

            if ($new_balance < 0){
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'new balance less than zero'));
                return false;
            }

            //生成交易流水号
            $trade_number = $this->systemService->genTradeNumber();
            //查询师傅
            $master = Master::find($cashOrder->master_id);

            $ret = MasterTradeLog::create([
                'trade_number'=>$trade_number,
                'master_id'=>$cashOrder->master_id,
                'master_name'=>$master->real_name,
                'direction'=>Params::TRADE_DIRECTION_OUT,
                'amount'=>$cashOrder->amount,
                'type'=>Params::TRADE_TYPE_CASH,
                'source'=>Params::TRADE_SOURCE_BALANCE,
                'balance'=>$new_balance,
                'assure_fund'=>$wallet->assure_fund,
                'order_number'=>$cashOrder->id,
                'order_serial_number'=>$cashOrder->order_number,
                'ip'=>getip(),
                'status'=>Params::TRADE_STATUS_WAITING,
            ]);

            if ($ret){
                DB::commit();
            }else{
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'cashLog fail'));
                DB::rollBack();
            }

            return $ret;
        }catch (\Exception $e){
            DB::rollBack();
            throw $e;
        }
    }

    public function returnAssureFundLog(MasterFund $fundOrder)
    {
        DB::beginTransaction();
        try{
            $wallet = MasterWallet::where('master_id',$fundOrder->master_id)->lockForUpdate()->first();
            $current_fund = $wallet->assure_fund;
            $new_fund = $current_fund - $fundOrder->amount;

            if ($new_fund < 0){
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'new assure fund less than zero'));
                return false;
            }

            //生成交易流水号
            $trade_number = $this->systemService->genTradeNumber();
            //查询师傅
            $master = Master::find($fundOrder->master_id);

            $ret = MasterTradeLog::create([
                'trade_number'=>$trade_number,
                'master_id'=>$fundOrder->master_id,
                'master_name'=>$master->real_name,
                'direction'=>Params::TRADE_DIRECTION_IN,
                'amount'=>$fundOrder->amount,
                'type'=>Params::TRADE_TYPE_RETURN_ASSURE,
                'source'=>Params::TRADE_SOURCE_SYSTEM,
                'balance'=>$wallet->balance,
                'assure_fund'=>$new_fund,
                'order_number'=>$fundOrder->id,
                'order_serial_number'=>$fundOrder->order_number,
                'ip'=>getip(),
                'status'=>Params::TRADE_STATUS_WAITING,
            ]);

            if ($ret){
                DB::commit();
            }else{
                Log::error(sprintf('%s/%s::%s[%d] %s',__NAMESPACE__,__CLASS__,__FUNCTION__,__LINE__-2,'returnAssureFundLog fail'));
                DB::rollBack();
            }

            return $ret;
        }catch (\Exception $e){
            DB::rollBack();
            throw $e;
        }
    }

}